<?php
/**
 * XGPHP 轻量级PHP框架
 * @link http://xgphp.xg3.cn
 * @version 2.0.0
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @author 讯高科技 <xungaokeji@qq.com>
*/
namespace xg;
use \helper\Arr;
use \helper\Checker;
use \xg\facade\Db;
use \xg\facade\Lang;

class Validate {
    protected $error;
    protected $rules = [];
    public function __construct(array $rules=[]) {
        $this->rules = Arr::extend($this->rules,$rules);
    }

    public function check($data) {
        foreach($this->rules as $attr=>$rule) {
            if(is_array($rule)) {
                if($rule['rules']){
                    foreach($rule['rules'] as $rulei) {
                        if(!$this->validate($rulei,$data,$attr)){
                            return false;
                        }
                    }
                }else{
                    if(!$this->validate($rule,$data,$attr))
                    return false;
                }
            }
        }
        return true;
    }

    public function getError(){
        if(is_array($this->error)){
            return Lang::get($this->error['message'],$this->error);
        }
        return $this->error;
    }

    public function validate($rule,$data,$attr){
        if(!($type = $rule['type'])){
            throw new \xg\Exception('validate rule type not defined');
        }
        if($type=='require'){
            if(!isset($data[$attr]) or !$data[$attr]){
                $this->error = $rule['message']?$rule['message']:['message'=>'"{:attr}" is required','attr'=>$attr];
                return false;
            }
        }elseif($type=='email'){
            if(!Checker::isEmail($data[$attr])){
                $this->error = $rule['message']?$rule['message']:['message'=>'email format is incorrect'];
                return false;
            }
        }elseif($type=='length'){
            if(isset($rule['min']) and strlen($data[$attr])<$rule['min']){
                $this->error = $rule['message']?$rule['message']:['message'=>'"{:attr}" min '.$rule['min'].' chars','attr'=>$attr];
                return false;
            }
            if(isset($rule['max']) and strlen($data[$attr])>$rule['max']){
                $this->error = $rule['message']?$rule['message']:['message'=>'"{:attr}" max '.$rule['min'].' chars','attr'=>$attr];
                return false;
            }
        }elseif($type=='repassword'){
            if($data['repassword']!=$data['password']){
                $this->error = $rule['message']?$rule['message']:['message'=>'repassword validate failed'];
                return false;
            }
        }elseif($type=='unique'){
            if($rule['table']){
                $db = Db::name($rule['table'])->where($attr, $data[$attr]);
                $pk = $rule['pk']?$rule['pk']:'id';
                if(isset($data[$pk])){
                    $db->where($pk, '<>', $data[$pk]);
                }
                if($db->value($attr)) {
                    $this->error = $rule['message']?$rule['message']:['message'=>'"{:attr}" has exists','attr'=>$attr];
                    return false;
                }
            }else{
                throw new \xg\Exception('validate unique table not defined');
            }
        }else{
            if(method_exists($this,$type=$type)){
                if(!($result = $this->$type($data[$attr],$rule))){
                    $this->error = $rule['message']?$rule['message']:$result;
                    return false;
                }
            }else{
                throw new \xg\Exception('validate method "{:type}" not exists',['type'=>$type]);
            }
        }
        return true;
    }
}